// 串口数据接收

/*
 
 RX为串口输入
 data_out为接收到的串口字节（18位）
 每接收完成一个字节，en_data_out就产生一个同步脉冲
 用户见到en_data_out即可收数
 波特率为4800，系统时钟频率24MHz

 状态规划

 状态1： 空闲识别；  // 一直为1即为空闲，如连续收12个1
 状态2： 等起始位；  // ~RX&RX_delay ,识别下降沿
 状态3： 收b0;       // 1.5T
 状态4： 收b1;       // 1T
 状态5： 收b2;       // 1T
 状态6： 收b3;       // 1T
 状态7： 收b4;       // 1T
 状态8： 收b5;       // 1T
 状态9： 收b6;       // 1T
 状态10：收b7;       // 1T 收满8bit数据后，跳回厂以等起始位状态。 

 ....

 */
`timescale 1ns/10ps
 module UART_RXer (
     clk,
     res,
     RX,
     data_out,
     en_data_out
 );
 input    clk;
 input    res;
 input    RX;
 output[7:0]    data_out; //接收字节输出
 output    en_data_out;   //输出使用

 reg[7:0] data_out;
 reg[7:0]    state;// 主状态机
 reg[12:0]    con;// 用于计算比特宽度
 reg[3:0]     con_bits; // 用于计算比特数
 reg          en_data_out;
 reg  RX_delay; // RX的延时
 always @(posedge clk or negedge res) begin
     if(~res) begin
         state<=0;con<=0;con_bits<=0;RX_delay<=0;data_out<=0;en_data_out<=0;
     end
     else begin
         RX_delay<=RX;
         case(state)
         0:// 等空闲
         begin
             if(con==4999)begin
                con<=0; 
             end
             else begin
                 con<=con+1;
             end
             if(con==0)begin
                 if(RX)begin
                     con_bits<=con_bits+1;
                 end
                 else begin
                     con_bits<=0;
                 end
             end

             if(con_bits===12)begin
                 state<=1;
             end
         end
         1:// 等起始位；
         begin
             en_data_out<=0;
             if(~RX&RX_delay)begin
                 state<=2;
             end            
         end
         2:// 收最低位b0;
         begin
             if(con==7499)begin  // 7500=1.5T
                 con<=0;
                 data_out[0]<=RX;
                 state<=3;
             end
             else begin
                 con<=con+1;
             end
         end
         3:// 接收b1
         begin
           if(con==4999)begin  // 5000=1T
                 con<=0;
                 data_out[1]<=RX;
                 state<=4;
             end
             else begin
                 con<=con+1;
             end  
         end
         4:// 接收b2
         begin
           if(con==4999)begin  // 5000=1T
                 con<=0;
                 data_out[2]<=RX;
                 state<=5;
             end
             else begin
                 con<=con+1;
             end    
         end
         5:// 接收 b3
         begin
             if(con==4999)begin  // 5000=1T
                 con<=0;
                 data_out[3]<=RX;
                 state<=6;
             end
             else begin
                 con<=con+1;
             end  
         end
         6:// 接收b4
         begin
             if(con==4999)begin  // 5000=1T
                 con<=0;
                 data_out[4]<=RX;
                 state<=7;
             end
             else begin
                 con<=con+1;
             end  
         end
         7:// 接收 b5
         begin
            if(con==4999)begin  // 5000=1T
                 con<=0;
                 data_out[5]<=RX;
                 state<=8;
             end
             else begin
                 con<=con+1;
             end   
         end
         8:// 接收 b6
         begin
             if(con==4999)begin  // 5000=1T
                 con<=0;
                 data_out[6]<=RX;
                 state<=9;
             end
             else begin
                 con<=con+1;
             end  
         end
         9:// 接收 b7
         begin
             if(con==4999)begin  // 5000=1T
                 con<=0;
                 data_out[7]<=RX;
                 state<=10;
             end
             else begin
                 con<=con+1;
             end  
         end
         10:// 产生全能脉冲
         begin
             en_data_out<=1;
             state<=1;
         end
         
         default:
         begin
            state<=0;
            con<=0;
            con_bits<=0; 
            en_data_out<=0;
         end

     endcase
     
 end

end
endmodule


//---------------testbench of UART_RXer ----------------------------
module UART_RXer_tb;

reg clk,res;
wire RX;
wire[7:0] data_out;
wire en_data_out;
reg[25:0] RX_send;// 里面装有串口字节发送数据

assign RX=RX_send[0]; // 连接RX

reg[12:0] con;

UART_RXer UART_RXer (  
     .clk(clk),
     .res(res),
     .RX(RX),
     .data_out(data_out),
     .en_data_out(en_data_out)
 );

 initial begin
     clk<=0;res<=0;RX_send<={1'b1,8'haa,1'b0,16'hffff};con<=0;
     #17 res<=1;
     #1000 $stop;
 end

 always #5 clk<=~clk;

always @(posedge clk) begin
    if(con==5000-1)begin
        con<=0;
    end
    else begin
        con<=con+1;
    end
    if(con==0) begin
        RX_send[24:0]<=RX_send[25:1];
        RX_send[25]<=RX_send[0];
    end
end

 endmodule